package qc.module.platform.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.enums.ResourceStatusFlagEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.platform.dto.dbTableSql.DBTableSqlDto;
import qc.module.platform.dto.dbTableSql.DBTableSqlSimpleDto;
import qc.module.platform.entity.QcDbTableSql;
import qc.module.platform.mapper.DBTableSqlMapper;
import qc.module.platform.repository.QcDbTableSqlRepository;

import java.util.List;
import java.util.Objects;

/**
 * DbTableSqlService
 *
 * @author QuCheng Tech
 * @since 2024/1/29
 */
@Service
public class DbTableSqlService {
    private QcDbTableSqlRepository repository;
    
    @Autowired
    private DbTableService dbTableService;

    @Autowired
    public void setRepository(QcDbTableSqlRepository repository) {
        this.repository = repository;
    }

    /***
     * 查询指定表的sql信息
     *
     * @param tableCode 指定的表代码
     * @param onlyValid 是否仅查询有效状态
     * @return java.util.List<qc.module.platform.dto.dbTableSql.DBTableSqlDto>
     * @author QuCheng Tech
     * @since 2024/1/29
     */
    public List<DBTableSqlDto> getTableAllSqls(String tableCode, boolean onlyValid) throws QCPromptException {
        List<QcDbTableSql> ens = getTableSqlEntities(tableCode, onlyValid, true);

        if (ens != null && ens.size() > 0x0) {
            return DBTableSqlMapper.MAPPER.toDtoList(ens);
        }

        return null;
    }

    /***
     * 查询指定表的sql简要信息
     *
     * @param tableCode 指定的表代码
     * @param onlyValid 是否仅查询有效状态
     * @return java.util.List<qc.module.platform.dto.dbTableSql.DBTableSqlSimpleDto>
     * @author QuCheng Tech
     * @since 2024/1/29
     */
    public List<DBTableSqlSimpleDto> getTableAllSqlSimples(String tableCode, boolean onlyValid) throws QCPromptException {
        List<QcDbTableSql> ens = getTableSqlEntities(tableCode, onlyValid, false);

        if (ens != null && ens.size() > 0x0) {
            return DBTableSqlMapper.MAPPER.toSimpleDtoList(ens);
        }

        return null;
    }

    /***
     * 查询指定表的sql实体类信息
     *
     * @param tableCode 指定的表代码
     * @param onlyValid 是否仅查询有效状态
     * @param includeFullInfo 是否包含完整信息
     * @return java.util.List<qc.module.platform.entity.QcDbTableSql>
     * @author QuCheng Tech
     * @since 2024/1/29
     */
    List<QcDbTableSql> getTableSqlEntities(String tableCode, boolean onlyValid, boolean includeFullInfo) throws QCPromptException {
        if (StringUtils.isBlank(tableCode))
            throw new QCPromptException("查询数据库表列信息时指定的数据库表代码不能为空");

        LambdaQueryWrapper<QcDbTableSql> wrapper = new LambdaQueryWrapper<>();

        //如果不是查询完整信息，设置仅查询部分列，不包含sql语句列
        if (!includeFullInfo)
            wrapper.select(QcDbTableSql::getTbcode, QcDbTableSql::getCode, QcDbTableSql::getName, QcDbTableSql::getOptype, QcDbTableSql::getEditflag);

        //根据表代码进行筛选
        wrapper.eq(QcDbTableSql::getTbcode, tableCode);

        if (onlyValid)
            wrapper.eq(QcDbTableSql::getFlag, ResourceStatusFlagEnum.NORMAL);

        //排序，排序号
        wrapper.orderByAsc(QcDbTableSql::getOdr);

        //查询数据
        return repository.selectList(wrapper);
    }

    /***
     * 获取指定表的指定sql信息
     *
     * @param tableCode 表编码
     * @param sqlCode sql代码
     * @return qc.module.platform.dto.dbTableSql.DBTableSqlDto
     * @author QuCheng Tech
     * @since 2024/1/29
     */
    public DBTableSqlDto get(String tableCode, String sqlCode) {
        LambdaQueryWrapper<QcDbTableSql> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(QcDbTableSql::getTbcode, tableCode);
        wrapper.eq(QcDbTableSql::getCode, sqlCode);

        QcDbTableSql en = repository.selectOne(wrapper);
        if (en != null)
            return DBTableSqlMapper.MAPPER.toDto(en);

        return null;
    }

    /**
     * 新增
     * @param dto
     * @return 成功返回null，失败返回错误信息
     * @author QuCheng Tech
     * @since 2024/3/13
     */
    public String add(DBTableSqlDto dto){
        // 1.新增对象判空
        if (Objects.isNull(dto)) return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getTbcode())) return QCUnifyReturnValue.Warn("数据库表编码不能为空");
        if (StringUtils.isBlank(dto.getCode())) return QCUnifyReturnValue.Warn("sql语句编码不能为空");
        if (StringUtils.isBlank(dto.getName())) return QCUnifyReturnValue.Warn("sql语句名称不能为空");
        if (StringUtils.isBlank(dto.getSqlstr())) return QCUnifyReturnValue.Warn("sql语句不能为空");
        if (StringUtils.isBlank(dto.getOptype())) return QCUnifyReturnValue.Warn("操作类型不能为空");

        // 2.判断数据库表编码对象是否存在
        if (!dbTableService.isExist(dto.getTbcode())) return QCUnifyReturnValue.Warn("数据库表编码不存在");

        // 3.判断新增对象是否存在
        if (isExist(dto.getTbcode(),dto.getCode())) return QCUnifyReturnValue.Warn("新增的sql语句对象已经存在");
        
        // 4.dto转换为entity
        QcDbTableSql en = DBTableSqlMapper.MAPPER.dtoToEntity(dto);
        
        // 5.保存数据
        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("新增数据失败");
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改
     * @param dto
     * @return 成功返回null，失败返回错误信息
     * @author QuCheng Tech
     * @since 2024/3/13
     */
    public String update(DBTableSqlDto dto){
        // 1.修改对象判空
        if (Objects.isNull(dto)) return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getTbcode())) return QCUnifyReturnValue.Warn("数据库表编码不能为空");
        if (StringUtils.isBlank(dto.getCode())) return QCUnifyReturnValue.Warn("sql语句编码不能为空");
        if (StringUtils.isBlank(dto.getName())) return QCUnifyReturnValue.Warn("sql语句名称不能为空");
        if (StringUtils.isBlank(dto.getSqlstr())) return QCUnifyReturnValue.Warn("sql语句不能为空");
        if (StringUtils.isBlank(dto.getOptype())) return QCUnifyReturnValue.Warn("操作类型不能为空");

        // 2.判断数据库表编码对象是否存在
        if (!dbTableService.isExist(dto.getTbcode())) return QCUnifyReturnValue.Warn("数据库表编码不存在");
        
        // 3.判断修改对象是否存在
        if (!isExist(dto.getTbcode(),dto.getCode())) return QCUnifyReturnValue.Warn("修改的sql语句对象不存在");
        
        // 4.dto转换为entity
        QcDbTableSql en = DBTableSqlMapper.MAPPER.editDtoToEntity(dto);
        
        // 5.修改数据
        LambdaUpdateWrapper<QcDbTableSql> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(QcDbTableSql::getTbcode,dto.getTbcode());
        wrapper.eq(QcDbTableSql::getCode,dto.getCode());
        repository.update(en,wrapper);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除
     * @param tableCode 数据库表编码
     * @param code sql语句编码
     * @return 成功返回null，失败返回错误信息
     * @author QuCheng Tech
     * @since 2024/3/13
     */
    public String delete(String tableCode,String code) throws QCPromptException {
        // 1.条件判空
        if (StringUtils.isBlank(tableCode)) throw new QCPromptException("数据库编码不能为空");
        if (StringUtils.isBlank(code)) throw new QCPromptException("sql语句编码不能为空");
        
        // 2.删除数据
        LambdaQueryWrapper<QcDbTableSql> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcDbTableSql::getTbcode,tableCode);
        wrapper.eq(QcDbTableSql::getCode,code);
        repository.delete(wrapper);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 根据指定数据库表编码和sql语句编码判断sql语句信息对象是否存在
     * @param tbCode 数据库表编码
     * @param code sql语句编码
     * @return 返回true表示存在，false表示不存在
     * @author Qucheng Tech
     * @since 2024/3/13
     */
    private boolean isExist(String tbCode,String code){
        LambdaQueryWrapper<QcDbTableSql> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QcDbTableSql::getTbcode,tbCode);
        wrapper.eq(QcDbTableSql::getCode,code);
        
        if (Objects.nonNull(repository.selectOne(wrapper))) return true;
        return false;
    }
}
